using System;
using System.Collections.Generic;
using WenYu.Core.Parser;

namespace WenYu.Core.CodeGen
{
    /// <summary>
    /// 代码生成器 - 将AST转换为中间代码(IR)
    /// 
    /// 流程:
    /// 1. 遍历AST树
    /// 2. 为每个节点生成对应的IR指令
    /// 3. 管理符号表和变量
    /// 4. 生成指令序列供Runtime执行
    /// 
    /// 对标需求: REQ-04 代码生成器
    /// </summary>
    public class CodeGenerator
    {
        /// <summary>生成的IR指令列表</summary>
        private List<IRInstruction> _instructions = new();
        
        /// <summary>符号表</summary>
        private SymbolTable _symbolTable = new();
        
        /// <summary>作用域栈 - 管理变量作用域，解决不同函数参数冲突问题</summary>
        private Stack<HashSet<string>> _scopeStack = new();
        
        /// <summary>当前函数的作用域中，用户参数名到Runtime参数名的映射</summary>
        private Dictionary<string, string> _currentFunctionParameterMapping;
        
        /// <summary>循环标签栈 - 管理嵌套循环的break/continue目标地址</summary>
        private Stack<(int breakTarget, int continueTarget)> _loopLabelStack = new();
        
        /// <summary>待回填的break指令列表 - 记录(指令索引, 所属循环深度)</summary>
        private List<int> _pendingBreakInstructions = new();
        
        /// <summary>待回填的continue指令列表 - 记录(指令索引, 所属循环深度)</summary>
        private List<int> _pendingContinueInstructions = new();
        
        public CodeGenerator()
        {
            _scopeStack.Push(new HashSet<string>()); // 全局作用域
            
            // 注册标准库函数
            _symbolTable.RegisterStandardLibrary(StandardLibraryRegistry.CreateDefault());
        }
        
        /// <summary>
        /// 生成IR指令
        /// </summary>
        public List<IRInstruction> Generate(Program ast)
        {
            if (ast == null)
                throw new ArgumentNullException(nameof(ast));
            
            _instructions.Clear();
            _symbolTable.Clear();
            _scopeStack.Clear();
            _scopeStack.Push(new HashSet<string>()); // 重置为全局作用域
            _loopLabelStack.Clear(); // 重置循环标签栈
            _pendingBreakInstructions.Clear(); // 重置待回填break列表
            _pendingContinueInstructions.Clear(); // 重置待回填continue列表
            
            // 分离函数定义和主程序语句
            var functions = new List<FunctionDeclaration>();
            var mainStatements = new List<Statement>();
            
            foreach (var statement in ast.Statements)
            {
                if (statement is FunctionDeclaration funcDecl)
                {
                    functions.Add(funcDecl);
                }
                else
                {
                    mainStatements.Add(statement);
                }
            }
            
            // 如果有函数定义,需要先跳过函数区
            if (functions.Count > 0)
            {
                // ===== 第一遍：收集所有函数签名并预注册到符号表 =====
                // 这样函数可以相互调用（支持前向引用）
                var functionEntryPlaceholders = new Dictionary<string, int>();
                foreach (var func in functions)
                {
                    var paramTypes = func.Parameters.ConvertAll(p => p.Type);
                    var placeholderAddress = -1; // 占位地址
                    _symbolTable.DefineFunction(func.Name, func.ReturnType, paramTypes, placeholderAddress);
                    functionEntryPlaceholders[func.Name] = -1; // 记录需要回填
                }
                
                // 生成跳转指令(占位),稍后回填
                var skipJumpIndex = _instructions.Count;
                _instructions.Add(new IRInstruction(IROpcode.Br, 0)); // 占位
                
                // ===== 第二遍：生成所有函数定义并更新入口地址 =====
                foreach (var func in functions)
                {
                    var actualEntryAddress = _instructions.Count;
                    
                    // 更新符号表中的函数入口地址
                    var funcInfo = _symbolTable.GetFunction(func.Name);
                    funcInfo.EntryAddress = actualEntryAddress;
                    
                    // 生成函数体（注意：不再重复注册函数）
                    GenerateFunctionBody(func);
                }
                
                // 回填跳转地址(跳到主程序开始)
                var mainStartAddress = _instructions.Count;
                _instructions[skipJumpIndex] = new IRInstruction(IROpcode.Br, mainStartAddress);
            }
            
            // 生成主程序语句
            foreach (var statement in mainStatements)
            {
                GenerateStatement(statement);
            }
            
            return _instructions;
        }
        
        /// <summary>生成语句的IR</summary>
        private void GenerateStatement(Statement statement)
        {
            switch (statement)
            {
                case VarDeclStatement varDecl:
                    GenerateVarDeclaration(varDecl);
                    break;
                
                case ExpressionStatement exprStmt:
                    GenerateExpression(exprStmt.Expression);
                    // 表达式语句的结果应该被打印（REPL模式）
                    // 但函数调用已经处理了输出，不需要额外的PRINT
                    if (!(exprStmt.Expression is FunctionCallExpression))
                    {
                        _instructions.Add(new IRInstruction(IROpcode.Call_Print, 1));
                    }
                    break;
                
                case AssignmentStatement assignStmt:
                    GenerateAssignment(assignStmt);
                    break;
                
                case FunctionDeclaration funcDecl:
                    GenerateFunctionDeclaration(funcDecl);
                    break;
                
                case ReturnStatement returnStmt:
                    GenerateReturnStatement(returnStmt);
                    break;
                
                case IfStatement ifStmt:
                    GenerateIfStatement(ifStmt);
                    break;
                
                case WhileStatement whileStmt:
                    GenerateWhileStatement(whileStmt);
                    break;
                
                case ForStatement forStmt:
                    GenerateForStatement(forStmt);
                    break;
                
                case BreakStatement:
                    if (_loopLabelStack.Count == 0)
                        throw new InvalidOperationException("停(break)语句只能在循环中使用");
                    // 先生成占位符指令，记录其索引以便后续回填
                    _pendingBreakInstructions.Add(_instructions.Count);
                    _instructions.Add(new IRInstruction(IROpcode.Br_Break, 0)); // 目标地址待回填
                    break;
                
                case ContinueStatement:
                    if (_loopLabelStack.Count == 0)
                        throw new InvalidOperationException("跳(continue)语句只能在循环中使用");
                    // 先生成占位符指令，记录其索引以便后续回填
                    _pendingContinueInstructions.Add(_instructions.Count);
                    _instructions.Add(new IRInstruction(IROpcode.Br_Continue, 0)); // 目标地址待回填
                    break;
                
                case ArrayDeclStatement arrayDecl:
                    GenerateArrayDeclaration(arrayDecl);
                    break;
                
                case ClassDeclaration classDecl:
                    GenerateClassDeclaration(classDecl);
                    break;
                
                case ObjectCreationStatement objCreation:
                    GenerateObjectCreation(objCreation);
                    break;
                
                default:
                    throw new NotSupportedException($"不支持的语句类型: {statement?.GetType().Name}");
            }
        }
        
        /// <summary>生成变量声明的IR</summary>
        private void GenerateVarDeclaration(VarDeclStatement varDecl)
        {
            // 如果有初始化表达式
            if (varDecl.Init != null)
            {
                // 1. 生成初始化表达式的代码 (结果在栈顶)
                GenerateExpression(varDecl.Init);
                
                // 2. 在符号表中声明变量
                _symbolTable.DefineVariable(varDecl.Name, varDecl.Type);
                
                // 3. 生成存储指令 (从栈顶弹出，存储到变量)
                _instructions.Add(new IRInstruction(IROpcode.Stloc, varDecl.Name));
            }
            else
            {
                // 仅声明，不初始化
                _symbolTable.DefineVariable(varDecl.Name, varDecl.Type);
            }
        }
        
        /// <summary>生成赋值语句的IR</summary>
        private void GenerateAssignment(AssignmentStatement assignStmt)
        {
            // 情况1：赋值给数组元素 arr【index】= value
            if (assignStmt.Target is ArrayAccessExpression arrayAccess)
            {
                // 1. 生成数组对象代码
                GenerateExpression(arrayAccess.Array);
                
                // 2. 生成索引代码
                GenerateExpression(arrayAccess.Index);
                
                // 3. 生成右值代码
                GenerateExpression(assignStmt.Value);
                
                // 4. 生成数组赋值指令
                _instructions.Add(new IRInstruction(IROpcode.Stelem));
                return;
            }
            
            // 情况2：赋值给对象字段 obj的field = value
            if (assignStmt.Target is MemberAccessExpression memberAccess)
            {
                // 1. 生成对象代码
                GenerateExpression(memberAccess.Object);
                
                // 2. 生成右值代码
                GenerateExpression(assignStmt.Value);
                
                // 3. 生成字段赋值指令
                _instructions.Add(new IRInstruction(IROpcode.Stfld, memberAccess.Member));
                return;
            }
            
            // 情况3：赋值给标识符
            if (assignStmt.Target is not IdentifierExpression ident)
                throw new NotSupportedException("MVP中仅支持赋值给变量、数组元素或对象字段");
            
            // 检查变量是否已定义（包括检查参数映射）
            bool isParameter = _currentFunctionParameterMapping != null && 
                              _currentFunctionParameterMapping.ContainsKey(ident.Name);
            bool isVariable = _symbolTable.HasVariable(ident.Name);
            
            if (!isParameter && !isVariable)
                throw new InvalidOperationException($"未定义的变量: {ident.Name}");
            
            // 生成右值代码
            GenerateExpression(assignStmt.Value);
            
            // 生成存储指令
            string targetName = isParameter 
                ? _currentFunctionParameterMapping![ident.Name]  // 参数映射名
                : ident.Name;  // 普通变量名
            _instructions.Add(new IRInstruction(IROpcode.Stloc, targetName));
        }
        
        /// <summary>生成表达式的IR</summary>
        private void GenerateExpression(Expression expression)
        {
            switch (expression)
            {
                case IntegerLiteral intLit:
                    _instructions.Add(new IRInstruction(IROpcode.Ldc_I4, intLit.Value));
                    break;
                
                case DoubleLiteral doubleLit:
                    _instructions.Add(new IRInstruction(IROpcode.Ldc_R8, doubleLit.Value));
                    break;
                
                case StringLiteral strLit:
                    _instructions.Add(new IRInstruction(IROpcode.Ldstr, strLit.Value));
                    break;
                
                case BooleanLiteral boolLit:
                    // 布尔值转换为整数: 真真=1, 假假=0
                    _instructions.Add(new IRInstruction(IROpcode.Ldc_I4, boolLit.Value ? 1 : 0));
                    break;
                
                case IdentifierExpression ident:
                    // 检查是否是函数参数
                    if (_currentFunctionParameterMapping != null && 
                        _currentFunctionParameterMapping.TryGetValue(ident.Name, out var paramName))
                    {
                        // 使用参数映射的名称（arg0, arg1, ...）
                        _instructions.Add(new IRInstruction(IROpcode.Ldloc, paramName));
                    }
                    else if (_symbolTable.HasVariable(ident.Name))
                    {
                        // 否则检查普通变量
                        _instructions.Add(new IRInstruction(IROpcode.Ldloc, ident.Name));
                    }
                    else
                    {
                        throw new InvalidOperationException($"未定义的变量: {ident.Name}");
                    }
                    break;
                
                case BinaryExpression binExpr:
                    GenerateBinaryExpression(binExpr);
                    break;
                
                case MemberAccessExpression memberExpr:
                    GenerateMemberExpression(memberExpr);
                    break;
                
                case FunctionCallExpression funcCall:
                    GenerateFunctionCall(funcCall);
                    break;
                
                case ArrayLiteral arrayLit:
                    GenerateArrayLiteral(arrayLit);
                    break;
                
                case ArrayAccessExpression arrayAccess:
                    GenerateArrayAccess(arrayAccess);
                    break;
                
                case UnaryExpression unaryExpr:
                    GenerateUnaryExpression(unaryExpr);
                    break;
                
                default:
                    throw new NotSupportedException($"不支持的表达式类型: {expression?.GetType().Name}");
            }
        }
        
        /// <summary>生成一元表达式的IR（如 -5, +3）</summary>
        private void GenerateUnaryExpression(UnaryExpression unaryExpr)
        {
            // 根据操作符生成指令
            switch (unaryExpr.Operator)
            {
                case "负": // 负号
                case "-":
                    // 先生成操作数代码，然后用 0 - operand 实现取负
                    _instructions.Add(new IRInstruction(IROpcode.Ldc_I4, 0));
                    GenerateExpression(unaryExpr.Operand);
                    _instructions.Add(new IRInstruction(IROpcode.Sub));
                    break;
                
                case "正": // 正号（不需要操作）
                case "+":
                    // 直接生成操作数，不需要额外操作
                    GenerateExpression(unaryExpr.Operand);
                    break;
                
                case "非": // 逻辑非
                case "!":
                    GenerateExpression(unaryExpr.Operand);
                    _instructions.Add(new IRInstruction(IROpcode.Not));
                    break;
                
                default:
                    throw new NotSupportedException($"不支持的一元操作符: {unaryExpr.Operator}");
            }
        }
        
        /// <summary>生成二元表达式的IR</summary>
        private void GenerateBinaryExpression(BinaryExpression binExpr)
        {
            // 1. 生成左操作数代码 (结果在栈顶)
            GenerateExpression(binExpr.Left);
            
            // 2. 生成右操作数代码 (结果在栈顶)
            GenerateExpression(binExpr.Right);
            
            // 3. 根据操作符生成对应的运算指令
            var opcode = GetOpcodeFromOperator(binExpr.Operator);
            _instructions.Add(new IRInstruction(opcode));
        }
        
        /// <summary>将文语操作符转换为IR操作码</summary>
        private IROpcode GetOpcodeFromOperator(string op)
        {
            return op switch
            {
                "+" => IROpcode.Add,
                "-" => IROpcode.Sub,
                "*" => IROpcode.Mul,
                "÷" => IROpcode.Div,
                "/" => IROpcode.Div,        // 备用除号
                "%" => IROpcode.Rem,
                
                "同" => IROpcode.Ceq,        // 相等
                "不同" => IROpcode.Cne,      // 不相等
                "《" => IROpcode.Clt,        // 小于（符号）
                "小于" => IROpcode.Clt,      // 小于（关键字）✅
                "不》" => IROpcode.Cle,      // 小于等于
                "》" => IROpcode.Cgt,        // 大于（符号）
                "大于" => IROpcode.Cgt,      // 大于（关键字）✅
                "不《" => IROpcode.Cge,      // 大于等于
                
                "且" => IROpcode.And,       // 逻辑与
                "或" => IROpcode.Or,        // 逻辑或
                
                _ => throw new NotSupportedException($"不支持的操作符: {op}")
            };
        }
        
        /// <summary>生成成员表达式的IR (e.g., "x的文字" 或 "宝马的价格")</summary>
        private void GenerateMemberExpression(MemberAccessExpression memberExpr)
        {
            var property = memberExpr.Member;
            
            // 先检查是否是对象字段访问
            // 如果对象是标识符，检查它是否是一个类对象
            if (memberExpr.Object is IdentifierExpression identExpr)
            {
                var objectName = identExpr.Name;
                if (_symbolTable.HasVariable(objectName))
                {
                    var varType = _symbolTable.GetVariableType(objectName);
                    // 检查该变量是否是类类型
                    if (_symbolTable.HasClass(varType))
                    {
                        var classInfo = _symbolTable.GetClass(varType);
                        // 检查字段是否存在
                        if (classInfo.Fields.ContainsKey(property))
                        {
                            // 这是对象字段访问
                            GenerateExpression(memberExpr.Object); // 加载对象
                            _instructions.Add(new IRInstruction(IROpcode.Ldfld, property));
                            return;
                        }
                    }
                }
            }
            
            // 如果不是对象字段访问，则按内置属性处理
            // 1. 生成对象表达式代码
            GenerateExpression(memberExpr.Object);
            
            // 2. 根据属性名生成对应的转换指令
            // 类型转换
            if (property == "文字")
            {
                _instructions.Add(new IRInstruction(IROpcode.Call, "内置_文字转换"));
            }
            // 长度属性
            else if (property == "长")
            {
                _instructions.Add(new IRInstruction(IROpcode.Call, "内置_长度"));
            }
            // 字符串操作
            else if (property == "反")
            {
                _instructions.Add(new IRInstruction(IROpcode.Call, "内置_反转"));
            }
            else if (property == "大写")
            {
                _instructions.Add(new IRInstruction(IROpcode.Call, "内置_大写"));
            }
            else if (property == "小写")
            {
                _instructions.Add(new IRInstruction(IROpcode.Call, "内置_小写"));
            }
            // 数组操作
            else if (property == "首")
            {
                _instructions.Add(new IRInstruction(IROpcode.Call, "内置_首元素"));
            }
            else if (property == "尾")
            {
                _instructions.Add(new IRInstruction(IROpcode.Call, "内置_尾元素"));
            }
            else
            {
                throw new NotSupportedException($"不支持的属性: {property}");
            }
        }
        
        /// <summary>生成函数调用的IR（统一处理标准库和用户函数）</summary>
        private void GenerateFunctionCall(FunctionCallExpression funcCall)
        {
            // 统一验证：检查函数是否存在
            if (!_symbolTable.HasFunction(funcCall.Name))
            {
                throw new InvalidOperationException($"未定义的函数: {funcCall.Name}");
            }
            
            // 统一验证：检查参数数量
            if (!_symbolTable.ValidateFunctionCall(funcCall.Name, funcCall.Arguments.Count, out var errorMessage))
            {
                throw new InvalidOperationException(errorMessage);
            }
            
            // 1. 生成所有参数代码（从左到右压栈）
            foreach (var arg in funcCall.Arguments)
            {
                GenerateExpression(arg);
            }
            
            // 2. 判断是标准库函数还是用户函数
            if (_symbolTable.IsStandardLibraryFunction(funcCall.Name))
            {
                // 标准库函数：生成 CALL 指令，函数名作为字符串
                GenerateStandardLibraryCall(funcCall);
            }
            else
            {
                // 用户函数：生成 CALL 指令，函数地址作为操作数
                GenerateUserFunctionCall(funcCall);
            }
        }
        
        /// <summary>生成标准库函数调用</summary>
        private void GenerateStandardLibraryCall(FunctionCallExpression funcCall)
        {
            // 特殊处理：输出函数使用 Call_Print 指令（向后兼容）
            if (funcCall.Name == "输出")
            {
                _instructions.Add(new IRInstruction(IROpcode.Call_Print, funcCall.Arguments.Count));
                return;
            }
            
            // 其他标准库函数：统一使用 "内置_" 前缀
            string builtinName = GetBuiltinFunctionName(funcCall.Name);
            _instructions.Add(new IRInstruction(IROpcode.Call, builtinName, funcCall.Arguments.Count));
        }
        
        /// <summary>生成用户函数调用</summary>
        private void GenerateUserFunctionCall(FunctionCallExpression funcCall)
        {
            var funcInfo = _symbolTable.GetFunction(funcCall.Name);
            // 生成 CALL 指令 (函数入口地址, 参数个数)
            _instructions.Add(new IRInstruction(IROpcode.Call, funcInfo.EntryAddress, funcCall.Arguments.Count));
        }
        
        /// <summary>获取标准库函数的内置名称</summary>
        private string GetBuiltinFunctionName(string funcName)
        {
            // 映射：文语函数名 → Runtime内置名称
            return funcName switch
            {
                // 输入增强函数
                "确认" => "内置_确认",
                "输入带提示" => "内置_输入带提示",
                "输入带默认值" => "内置_输入带默认值",
                
                // 数学函数
                "绝对值" => "内置_绝对值",
                "最大值" => "内置_最大值",
                "最小值" => "内置_最小值",
                "幂" => "内置_幂",
                "平方根" => "内置_平方根",
                "向上取整" => "内置_向上取整",
                "向下取整" => "内置_向下取整",
                
                // 默认：加上"内置_"前缀
                _ => $"内置_{funcName}"
            };
        }
        
        
        /// <summary>生成函数定义的IR（已废弃，保留用于类方法）</summary>
        private void GenerateFunctionDeclaration(FunctionDeclaration funcDecl)
        {
            // 1. 进入新的函数作用域
            _scopeStack.Push(new HashSet<string>());
            
            // 2. 记录函数入口地址（当前指令位置）
            var entryAddress = _instructions.Count;
            
            // 3. 在符号表中注册函数
            var paramTypes = funcDecl.Parameters.ConvertAll(p => p.Type);
            _symbolTable.DefineFunction(funcDecl.Name, funcDecl.ReturnType, paramTypes, entryAddress);
            
            // 4. 生成函数体
            GenerateFunctionBodyInternal(funcDecl);
            
            // 5. 退出函数作用域
            _scopeStack.Pop();
        }
        
        /// <summary>生成函数体的IR（假设函数已在符号表中注册）</summary>
        private void GenerateFunctionBody(FunctionDeclaration funcDecl)
        {
            // 1. 进入新的函数作用域
            _scopeStack.Push(new HashSet<string>());
            
            // 记录需要清理的参数变量
            var parametersToCleanup = new List<string>();
            foreach (var param in funcDecl.Parameters)
            {
                parametersToCleanup.Add(param.Name);
            }
            
            // 2. 生成函数体内部代码
            GenerateFunctionBodyInternal(funcDecl);
            
            // 3. 清理参数变量（从符号表中移除，避免与下一个函数的参数冲突）
            foreach (var paramName in parametersToCleanup)
            {
                _symbolTable.RemoveVariable(paramName);
            }
            
            // 4. 退出函数作用域
            _scopeStack.Pop();
        }
        
        /// <summary>生成函数体内部代码（参数处理和语句生成）</summary>
        private void GenerateFunctionBodyInternal(FunctionDeclaration funcDecl)
        {
            // 1. 创建参数映射（用户参数名 -> Runtime参数名arg0/arg1/...）
            var parameterMapping = new Dictionary<string, string>();
            for (int i = 0; i < funcDecl.Parameters.Count; i++)
            {
                var paramUserName = funcDecl.Parameters[i].Name;
                var paramType = funcDecl.Parameters[i].Type;
                var paramRuntimeName = $"arg{i}";
                parameterMapping[paramUserName] = paramRuntimeName;
                _scopeStack.Peek().Add(paramUserName); // 记录在作用域中
                
                // 【修复】将参数注册到符号表，这样函数体内可以访问参数
                if (!_symbolTable.HasVariable(paramUserName))
                {
                    _symbolTable.DefineVariable(paramUserName, paramType);
                }
                
                // 生成代码：从argN加载值并存储到用户参数名
                _instructions.Add(new IRInstruction(IROpcode.Ldloc, paramRuntimeName));
                _instructions.Add(new IRInstruction(IROpcode.Stloc, paramUserName));
            }
            
            // 2. 保存参数映射供函数体访问
            _currentFunctionParameterMapping = parameterMapping;
            
            // 3. 生成函数体代码
            foreach (var statement in funcDecl.Body.Statements)
            {
                GenerateStatement(statement);
            }
            
            // 4. 清空参数映射
            _currentFunctionParameterMapping = null;
            
            // 5. 如果函数末尾没有return，自动添加RET指令
            if (funcDecl.Body.Statements.Count == 0 || 
                !(funcDecl.Body.Statements[^1] is ReturnStatement))
            {
                _instructions.Add(new IRInstruction(IROpcode.Ret));
            }
        }
        
        /// <summary>生成返回语句的IR</summary>
        private void GenerateReturnStatement(ReturnStatement returnStmt)
        {
            // 如果有返回值，先将返回值计算并压栈
            if (returnStmt.HasValue && returnStmt.Value != null)
            {
                GenerateExpression(returnStmt.Value);
            }
            
            // 生成RET指令
            _instructions.Add(new IRInstruction(IROpcode.Ret));
        }
        
        /// <summary>生成If语句的IR</summary>
        private void GenerateIfStatement(IfStatement ifStmt)
        {
            // 1. 生成条件表达式代码（结果在栈顶）
            GenerateExpression(ifStmt.Condition);
            
            // 2. 生成JMP_IF_FALSE指令（条件为false时跳转）
            var jumpToElseIndex = _instructions.Count;
            _instructions.Add(new IRInstruction(IROpcode.Brfalse, 0)); // 占位，稍后回填
            
            // 3. 生成then块代码
            foreach (var statement in ifStmt.ThenBlock.Statements)
            {
                GenerateStatement(statement);
            }
            
            // 4. 如果有else块
            if (ifStmt.ElseBlock != null && ifStmt.ElseBlock.Statements.Count > 0)
            {
                // 4.1 在then块末尾添加JMP指令跳过else块
                var jumpOverElseIndex = _instructions.Count;
                _instructions.Add(new IRInstruction(IROpcode.Br, 0)); // 占位
                
                // 4.2 回填JMP_IF_FALSE的目标地址（跳到else块开始）
                var elseStartAddress = _instructions.Count;
                _instructions[jumpToElseIndex] = new IRInstruction(IROpcode.Brfalse, elseStartAddress);
                
                // 4.3 生成else块代码
                foreach (var statement in ifStmt.ElseBlock.Statements)
                {
                    GenerateStatement(statement);
                }
                
                // 4.4 回填JMP的目标地址（跳到if-else后面）
                var afterIfAddress = _instructions.Count;
                _instructions[jumpOverElseIndex] = new IRInstruction(IROpcode.Br, afterIfAddress);
            }
            else
            {
                // 没有else块，回填JMP_IF_FALSE直接跳到if语句后面
                var afterIfAddress = _instructions.Count;
                _instructions[jumpToElseIndex] = new IRInstruction(IROpcode.Brfalse, afterIfAddress);
            }
        }
        
        /// <summary>生成While语句的IR</summary>
        private void GenerateWhileStatement(WhileStatement whileStmt)
        {
            // 1. 记录循环开始位置
            var loopStartAddress = _instructions.Count;
            
            // 2. 生成条件表达式代码
            GenerateExpression(whileStmt.Condition);
            
            // 3. 生成JMP_IF_FALSE指令（条件为false时跳出循环）
            var jumpOutIndex = _instructions.Count;
            _instructions.Add(new IRInstruction(IROpcode.Brfalse, 0)); // 占位
            
            // 3.5. 记录待回填列表的起始位置
            var breakListStartIndex = _pendingBreakInstructions.Count;
            var continueListStartIndex = _pendingContinueInstructions.Count;
            
            // 4. 推入循环标签 (占位值，break/continue会添加到待回填列表)
            _loopLabelStack.Push((0, loopStartAddress)); // continue目标=循环开始
            
            // 5. 生成循环体代码
            foreach (var statement in whileStmt.Body.Statements)
            {
                GenerateStatement(statement);
            }
            
            // 6. 生成JMP指令跳回循环开始
            _instructions.Add(new IRInstruction(IROpcode.Br, loopStartAddress));
            
            // 6.5 记录循环结束位置（作为break的目标）- 必须在JMP之后
            var afterLoopAddress = _instructions.Count;
            
            // 7. 回填这个循环内的break指令
            for (int i = breakListStartIndex; i < _pendingBreakInstructions.Count; i++)
            {
                var breakInstructionIndex = _pendingBreakInstructions[i];
                _instructions[breakInstructionIndex] = new IRInstruction(IROpcode.Br_Break, afterLoopAddress);
            }
            
            // 8. 回填这个循环内的continue指令
            for (int i = continueListStartIndex; i < _pendingContinueInstructions.Count; i++)
            {
                var continueInstructionIndex = _pendingContinueInstructions[i];
                _instructions[continueInstructionIndex] = new IRInstruction(IROpcode.Br_Continue, loopStartAddress);
            }
            
            // 9. 弹出循环标签
            _loopLabelStack.Pop();
            
            // 10. 回填JMP_IF_FALSE的目标地址（循环结束位置）
            _instructions[jumpOutIndex] = new IRInstruction(IROpcode.Brfalse, afterLoopAddress);
        }
        
        /// <summary>生成For语句的IR</summary>
        private void GenerateForStatement(ForStatement forStmt)
        {
            // For语句: 复 变量 从 起始 至 结束 步 步长 { 循环体 }
            // 需要根据步长正负选择不同的比较逻辑:
            // - 正步长: while (变量 <= 结束) { 循环体; 变量 += 步长 }
            // - 负步长: while (变量 >= 结束) { 循环体; 变量 += 步长 }
            
            // 1. 在符号表中定义循环变量（如果不存在）
            if (!_symbolTable.HasVariable(forStmt.Variable))
            {
                _symbolTable.DefineVariable(forStmt.Variable, "整型");
            }
            _scopeStack.Peek().Add(forStmt.Variable); // 记录在当前作用域
            
            // 2. 初始化循环变量 (变量 = 起始)
            GenerateExpression(forStmt.Start);
            _instructions.Add(new IRInstruction(IROpcode.Stloc, forStmt.Variable));
            
            // 3. 检测步长的正负性
            // 我们需要在运行时判断，所以生成一个临时变量存储步长，然后在循环前判断
            // 为简化，我们先尝试静态分析步长表达式
            bool isNegativeStep = IsNegativeExpression(forStmt.Step);
            
            // 4. 记录循环开始位置
            var loopStartAddress = _instructions.Count;
            
            // 5. 生成条件检查
            // 正步长: 变量 <= 结束  =>  变量 < 结束+1
            // 负步长: 变量 >= 结束  =>  !(变量 < 结束)
            _instructions.Add(new IRInstruction(IROpcode.Ldloc, forStmt.Variable));
            GenerateExpression(forStmt.End);
            
            if (isNegativeStep)
            {
                // 负步长: 变量 >= 结束  =>  结束 < 变量+1  =>  结束 < 变量+1
                // 更简单: !(变量 < 结束)
                _instructions.Add(new IRInstruction(IROpcode.Clt)); // 变量 < 结束
                _instructions.Add(new IRInstruction(IROpcode.Not)); // !(变量 < 结束) 即 变量 >= 结束
            }
            else
            {
                // 正步长: 变量 <= 结束  =>  变量 < 结束+1
                _instructions.Add(new IRInstruction(IROpcode.Ldc_I4, 1));
                _instructions.Add(new IRInstruction(IROpcode.Add));
                _instructions.Add(new IRInstruction(IROpcode.Clt)); // 变量 < 结束+1
            }
            
            // 6. 生成JMP_IF_FALSE（条件为false时跳出循环）
            var jumpOutIndex = _instructions.Count;
            _instructions.Add(new IRInstruction(IROpcode.Brfalse, 0)); // 占位
            
            // 6.5. 记录当前循环深度和开始时的待回填列表大小
            var loopDepth = _loopLabelStack.Count;
            var breakListStartIndex = _pendingBreakInstructions.Count;
            var continueListStartIndex = _pendingContinueInstructions.Count;
            
            // 6.6. 推入循环标签（占位值，break/continue会添加到待回填列表）
            _loopLabelStack.Push((0, 0)); // 占位值
            
            // 7. 生成循环体代码
            foreach (var statement in forStmt.Body.Statements)
            {
                GenerateStatement(statement);
            }
            
            // 7.5 记录变量更新处（作为continue的目标）
            var updateStartAddress = _instructions.Count;
            
            // 8. 更新循环变量 (变量 = 变量 + 步长)
            _instructions.Add(new IRInstruction(IROpcode.Ldloc, forStmt.Variable));
            GenerateExpression(forStmt.Step);
            _instructions.Add(new IRInstruction(IROpcode.Add));
            _instructions.Add(new IRInstruction(IROpcode.Stloc, forStmt.Variable));
            
            // 9. 生成JMP指令跳回循环开始
            _instructions.Add(new IRInstruction(IROpcode.Br, loopStartAddress));
            
            // 9.5 记录循环结束位置（作为break的目标） - 必须在JMP之后
            var afterLoopAddress = _instructions.Count;
            
            // 10. 回填这个循环内的break指令
            for (int i = breakListStartIndex; i < _pendingBreakInstructions.Count; i++)
            {
                var breakInstructionIndex = _pendingBreakInstructions[i];
                _instructions[breakInstructionIndex] = new IRInstruction(IROpcode.Br_Break, afterLoopAddress);
            }
            
            // 11. 回填这个循环内的continue指令
            for (int i = continueListStartIndex; i < _pendingContinueInstructions.Count; i++)
            {
                var continueInstructionIndex = _pendingContinueInstructions[i];
                _instructions[continueInstructionIndex] = new IRInstruction(IROpcode.Br_Continue, updateStartAddress);
            }
            
            // 12. 弹出循环标签
            _loopLabelStack.Pop();
            
            // 13. 回填JMP_IF_FALSE的目标地址（循环结束位置）
            _instructions[jumpOutIndex] = new IRInstruction(IROpcode.Brfalse, afterLoopAddress);
        }
        
        /// <summary>静态分析表达式是否为负数</summary>
        private bool IsNegativeExpression(Expression expr)
        {
            // 尝试静态分析表达式是否为负数
            switch (expr)
            {
                case IntegerLiteral intLit:
                    return intLit.Value < 0;
                
                case DoubleLiteral doubleLit:
                    return doubleLit.Value < 0;
                
                case UnaryExpression unaryExpr when unaryExpr.Operator == "-" || unaryExpr.Operator == "负":
                    // 负号表达式，例如 -1
                    // 检查操作数是否为正数
                    if (unaryExpr.Operand is IntegerLiteral innerInt)
                        return innerInt.Value > 0; // -5 是负数
                    if (unaryExpr.Operand is DoubleLiteral innerDouble)
                        return innerDouble.Value > 0;
                    return false; // 无法静态判断
                
                case BinaryExpression binExpr when binExpr.Operator == "减":
                    // 简单情况: 0 - 1
                    if (binExpr.Left is IntegerLiteral leftInt && leftInt.Value == 0)
                    {
                        if (binExpr.Right is IntegerLiteral rightInt)
                            return rightInt.Value > 0;
                    }
                    return false;
                
                default:
                    return false; // 无法静态判断，假设为正
            }
        }
        
        /// <summary>生成数组字面量的IR</summary>
        private void GenerateArrayLiteral(ArrayLiteral arrayLit)
        {
            // 1. 生成数组元素代码
            foreach (var element in arrayLit.Elements)
            {
                GenerateExpression(element);
            }
            
            // 2. 生成数组创建指令 (元素个数)
            _instructions.Add(new IRInstruction(IROpcode.Newarr, arrayLit.Elements.Count));
        }
        
        /// <summary>生成数组访问的IR</summary>
        private void GenerateArrayAccess(ArrayAccessExpression arrayAccess)
        {
            // 1. 生成数组对象代码
            GenerateExpression(arrayAccess.Array);
            
            // 2. 生成索引代码
            GenerateExpression(arrayAccess.Index);
            
            // 3. 生成数组元素访问指令
            _instructions.Add(new IRInstruction(IROpcode.Ldelem));
        }

        /// <summary>生成数组声明的IR</summary>
        private void GenerateArrayDeclaration(ArrayDeclStatement arrayDecl)
        {
            // 1. 如果有初值，生成初值表达式
            if (arrayDecl.Init != null)
            {
                GenerateExpression(arrayDecl.Init);
            }
            // 2. 如果指定了长度，创建指定大小的数组
            else if (arrayDecl.Length != null)
            {
                GenerateExpression(arrayDecl.Length);
                _instructions.Add(new IRInstruction(IROpcode.Newarr));
            }
            
            // 3. 在符号表中定义数组变量
            _symbolTable.DefineVariable(arrayDecl.Name, arrayDecl.ElementType + "组");
            
            // 4. 生成存储指令
            _instructions.Add(new IRInstruction(IROpcode.Stloc, arrayDecl.Name));
        }
        
        /// <summary>生成类定义的IR</summary>
        private void GenerateClassDeclaration(ClassDeclaration classDecl)
        {
            // 1. 收集字段信息
            var fields = new Dictionary<string, string>();
            var fieldDefaults = new Dictionary<string, object?>();
            
            foreach (var field in classDecl.Fields)
            {
                fields[field.Name] = field.Type;
                
                // 收集默认值（如果有）
                if (field.DefaultValue != null)
                {
                    // 简单处理：只支持字面量默认值
                    object? defaultValue = null;
                    if (field.DefaultValue is IntegerLiteral intLit)
                        defaultValue = intLit.Value;
                    else if (field.DefaultValue is DoubleLiteral doubleLit)
                        defaultValue = doubleLit.Value;
                    else if (field.DefaultValue is StringLiteral strLit)
                        defaultValue = strLit.Value;
                    else if (field.DefaultValue is BooleanLiteral boolLit)
                        defaultValue = boolLit.Value;
                    
                    fieldDefaults[field.Name] = defaultValue;
                }
            }
            
            // 2. 收集成员函数信息
            var methods = new Dictionary<string, SymbolTable.FunctionInfo>();
            
            foreach (var method in classDecl.Methods)
            {
                // 为每个成员函数生成代码
                var methodFullName = $"{classDecl.Name}::{method.Name}";
                var entryAddress = _instructions.Count;
                
                // 成员函数需要一个隐式的this参数
                var paramTypes = new List<string> { classDecl.Name }; // this参数
                foreach (var param in method.Parameters)
                {
                    paramTypes.Add(param.Type);
                }
                
                // 记录函数信息
                methods[method.Name] = new SymbolTable.FunctionInfo
                {
                    Name = methodFullName,
                    ReturnType = method.ReturnType,
                    ParameterTypes = paramTypes,
                    EntryAddress = entryAddress
                };
                
                // 生成成员函数的IR代码
                GenerateMethodBody(classDecl.Name, method);
            }
            
            // 3. 在符号表中注册类信息
            _symbolTable.DefineClass(classDecl.Name, fields, fieldDefaults, methods);
        }
        
        /// <summary>生成成员函数体的IR</summary>
        private void GenerateMethodBody(string className, ClassMethod method)
        {
            // 进入新作用域
            _scopeStack.Push(new HashSet<string>());
            
            // 创建参数映射（包括隐式this参数）
            _currentFunctionParameterMapping = new Dictionary<string, string>();
            _currentFunctionParameterMapping["this"] = "arg0"; // 隐式this
            
            int argIndex = 1;
            foreach (var param in method.Parameters)
            {
                var runtimeName = $"arg{argIndex}";
                _currentFunctionParameterMapping[param.Name] = runtimeName;
                
                // 生成参数加载和存储指令
                _instructions.Add(new IRInstruction(IROpcode.Ldloc, runtimeName));
                _instructions.Add(new IRInstruction(IROpcode.Stloc, param.Name));
                
                argIndex++;
            }
            
            // 生成函数体
            foreach (var stmt in method.Body.Statements)
            {
                GenerateStatement(stmt);
            }
            
            // 如果函数没有显式返回，添加默认返回
            if (method.ReturnType == null && 
                (method.Body.Statements.Count == 0 || 
                 !(method.Body.Statements[method.Body.Statements.Count - 1] is ReturnStatement)))
            {
                _instructions.Add(new IRInstruction(IROpcode.Ret, null)); // 无返回值
            }
            
            // 退出作用域
            _currentFunctionParameterMapping = null;
            _scopeStack.Pop();
        }
        
        /// <summary>生成对象创建的IR</summary>
        private void GenerateObjectCreation(ObjectCreationStatement objCreation)
        {
            // 1. 检查类是否存在
            if (!_symbolTable.HasClass(objCreation.ClassName))
            {
                throw new InvalidOperationException($"未定义的类: {objCreation.ClassName}");
            }
            
            var classInfo = _symbolTable.GetClass(objCreation.ClassName);
            
            // 2. 生成对象创建指令：OBJECT_NEW 类名（对象在栈顶）
            _instructions.Add(new IRInstruction(IROpcode.Newobj, objCreation.ClassName));
            
            // 3. 先存储对象到临时变量，然后处理属性初始化
            // 在符号表中定义对象变量
            _symbolTable.DefineVariable(objCreation.ObjectName, objCreation.ClassName);
            
            // 存储对象引用（栈顶 -> 变量）
            _instructions.Add(new IRInstruction(IROpcode.Stloc, objCreation.ObjectName));
            
            // 4. 处理属性初始化
            if (objCreation.Initializers.Count > 0)
            {
                // 现在对象已存储在变量中，可以加载并设置字段
                foreach (var init in objCreation.Initializers)
                {
                    // 检查字段是否存在
                    if (!classInfo.Fields.ContainsKey(init.Name))
                    {
                        throw new InvalidOperationException($"类 '{objCreation.ClassName}' 中不存在字段 '{init.Name}'");
                    }
                    
                    // 加载对象引用
                    _instructions.Add(new IRInstruction(IROpcode.Ldloc, objCreation.ObjectName));
                    
                    // 生成初始化值表达式
                    GenerateExpression(init.Value);
                    
                    // 设置字段：SET_FIELD 字段名（对象和值在栈上）
                    _instructions.Add(new IRInstruction(IROpcode.Stfld, init.Name));
                }
            }
        }
        
        /// <summary>获取生成的指令数量</summary>
        public int InstructionCount => _instructions.Count;
        
        /// <summary>获取定义的变量数量</summary>
        public int VariableCount => _symbolTable.VariableCount;
        
        /// <summary>获取符号表（用于Runtime访问类信息）</summary>
        public SymbolTable GetSymbolTable() => _symbolTable;
    }
}
